﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Data.Entity;
using WebMatrix.WebData;
using System.Web.Security;

using AesApplication.Models;

namespace AesApplication
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();

            // XXX: Add AesContext initializer to seed with test data.
            System.Data.Entity.Database.SetInitializer(new Initializer());

            // XXX: Force database to initialize.
            // !!! THIS WILL WIPE THE DATABASE EVERY TIME THE SERVER IS STARTED !!!
            // Wiping the database is unacceptable for real production code,
            // but it is done here for development purposes!
            // This is a hack to make sure everything is initialized in the proper order.
            System.Console.WriteLine("Forcing database initialization NOW");

            // Force-initialize both contexts
            using (AesContext ctx = new AesContext())
            {
                // Because our initializer uses DropCreateDatabaseAlways,
                // this will wipe and reset the AesContext tables.
                ctx.Database.Initialize(true);
            }
            using (UsersContext ctx = new UsersContext())
            {
                // This will add the UserProfiles table.
                ctx.Database.Initialize(true);
            }

            // Initialize Web Security stuff
            WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

            // Add Roles and test accounts.
            Roles.CreateRole("Staffing Expert");
            Roles.CreateRole("Hiring Specialist");
            Roles.CreateRole("Hiring Expert");
            Roles.CreateRole("Hiring Manager");
            Roles.CreateRole("Store Manager");
            Roles.CreateRole("IT Support");
            WebSecurity.CreateUserAndAccount("StaffingExpert", "pass");
            WebSecurity.CreateUserAndAccount("HiringExpert", "pass");
            WebSecurity.CreateUserAndAccount("HiringSpecialist", "pass");
            WebSecurity.CreateUserAndAccount("HiringManager", "pass");
            WebSecurity.CreateUserAndAccount("HMWorth", "pass");
            WebSecurity.CreateUserAndAccount("StoreManager", "pass");
            WebSecurity.CreateUserAndAccount("StoreAutManager", "pass");
            WebSecurity.CreateUserAndAccount("IT", "pass");
            Roles.AddUserToRole("StaffingExpert", "Staffing Expert");
            Roles.AddUserToRole("HiringExpert", "Hiring Expert");
            Roles.AddUserToRole("HiringSpecialist", "Hiring Specialist");
            Roles.AddUserToRole("HiringManager", "Hiring Manager");
            Roles.AddUserToRole("StoreManager", "Store Manager");
            Roles.AddUserToRole("IT", "IT Support");
            
            //Initializer Variables (Also in DBModels.cs Seed Data.
            string storeAut = "Autumn Avenue";
            string storeWorth = "Worthington Way";
            string storeHamp = "Hampshire Highway";
            string departmentElec = "Electronics";
            string departmentMens = "Men's Wear";
            string departmentWomens = "Women's Wear";
            string departmentToys = "Toys";
            string departmentFood = "Food";
            string departmentTools = "Tools";
            string departmentFurniture = "Furniture";

            // Assign "HiringManager" as a manager of some departments.
            using (AesContext ctx = new AesContext())
            {
                int managerId = WebSecurity.GetUserId("HiringManager");

                List<DepartmentManager> assignments = new List<DepartmentManager>{
                    new DepartmentManager { DepartmentID=(from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeAut &&
                            department.Name == departmentElec
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentElec
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentMens
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentWomens
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentToys
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeHamp &&
                            department.Name == departmentFood
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeHamp &&
                            department.Name == departmentTools
                         select department.ID).FirstOrDefault(), UserID = managerId },
                };
                assignments.ForEach(x => ctx.DepartmentManagers.Add(x));

                ctx.SaveChanges();
            }

            // Assign "HiringManager" as a manager of some departments.
            using (AesContext ctx = new AesContext())
            {
                int managerId = WebSecurity.GetUserId("HMWorth");

                List<DepartmentManager> assignments = new List<DepartmentManager>{
                    new DepartmentManager { DepartmentID=(from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentElec
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentMens
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentWomens
                         select department.ID).FirstOrDefault(), UserID = managerId },
                    new DepartmentManager { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                         where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentToys
                         select department.ID).FirstOrDefault(), UserID = managerId },
                };
                assignments.ForEach(x => ctx.DepartmentManagers.Add(x));

                ctx.SaveChanges();
            }

            //Mock Data     :: HiringSpecialist
            // Store        :: ALL
            // Department   :: ALL
            using (AesContext ctx = new AesContext())
            {
                int hiringId = WebSecurity.GetUserId("HiringSpecialist");

                List<DepartmentSpecialist> assignments = new List<DepartmentSpecialist>{
                    new DepartmentSpecialist { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                        where department.StoreID == store.ID &&
                            store.Name == storeAut &&
                            department.Name == departmentElec
                        select department.ID).FirstOrDefault(), UserID =  hiringId },
                    new DepartmentSpecialist { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                        where department.StoreID == store.ID &&
                            store.Name == storeAut &&
                            department.Name == departmentWomens
                        select department.ID).FirstOrDefault(), UserID =  hiringId },
                    new DepartmentSpecialist { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                        where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentElec
                        select department.ID).FirstOrDefault(), UserID =  hiringId },
                    new DepartmentSpecialist { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                        where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentMens
                        select department.ID).FirstOrDefault(), UserID =  hiringId },
                    new DepartmentSpecialist { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                        where department.StoreID == store.ID &&
                            store.Name == storeWorth &&
                            department.Name == departmentWomens
                        select department.ID).FirstOrDefault(), UserID =  hiringId },
                    new DepartmentSpecialist { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                        where department.StoreID == store.ID &&
                            store.Name == storeHamp &&
                            department.Name == departmentFood
                        select department.ID).FirstOrDefault(), UserID =  hiringId },
                    new DepartmentSpecialist { DepartmentID = (from department in ctx.Departments from store in ctx.Stores
                        where department.StoreID == store.ID &&
                            store.Name == storeHamp &&
                            department.Name == departmentTools
                        select department.ID).FirstOrDefault(), UserID =  hiringId },
                };

                assignments.ForEach(x => ctx.DepartmentSpecialists.Add(x));

                ctx.SaveChanges();

            }

            //Mock Data     :: StoreManager
            // Store        :: ALL
            using (AesContext ctx = new AesContext())
            {
                int storeId = WebSecurity.GetUserId("StoreManager");

                List<StoreManager> assignments = new List<StoreManager>{
                    new StoreManager { StoreID = (from store in ctx.Stores
                        where store.Name == storeAut
                        select store.ID).FirstOrDefault(), UserID =  storeId },
                    new StoreManager { StoreID = (from store in ctx.Stores
                        where store.Name == storeHamp
                        select store.ID).FirstOrDefault(), UserID =  storeId },
                    new StoreManager { StoreID = (from store in ctx.Stores
                        where store.Name == storeWorth
                        select store.ID).FirstOrDefault(), UserID =  storeId },
                };

                assignments.ForEach(x => ctx.StoreManagers.Add(x));

                ctx.SaveChanges();

            }

            //Mock Data     :: StoreAutManager
            // Store        :: ALL
            using (AesContext ctx = new AesContext())
            {
                int storeId = WebSecurity.GetUserId("StoreAutManager");

                List<StoreManager> assignments = new List<StoreManager>{
                    new StoreManager { StoreID = (from store in ctx.Stores
                        where store.Name == storeAut
                        select store.ID).FirstOrDefault(), UserID =  storeId },
                };

                assignments.ForEach(x => ctx.StoreManagers.Add(x));

                ctx.SaveChanges();

            }
            System.Console.WriteLine("DONE");
        }
    }
}